import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from sklearn.preprocessing import MinMaxScaler, StandardScaler


# 设置 matplotlib 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为 SimHei（黑体）
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 1.------------------------数据导入和输出----------------------------------
file_path = 'air_quality.xls'  # 文件路径
df = pd.read_excel(file_path, sheet_name='Sheet1', skiprows=1)  #第一行为空，省略掉

# # 检查列名（------测试-----）
# print("原始列名:", df.columns)


# 将时间列转换为datetime类型
df['时段'] = pd.to_datetime(df['时段'])

# 测试查看数据（------测试-----）
# print(df.head())

# 数据导出
output_file_path = 'output_data.xlsx'  # 输出文件路径
df.to_excel(output_file_path, index=False)


# 数据不合理导致无法可视化，所以在这里进行了部分数据处理
pd.set_option('future.no_silent_downcasting', True)
df.replace('-99.0(E)', np.nan, inplace=True)


# 2.-----------------------不同维度的数据可视化-------------------------------
# 绘制PM2.5随时间的变化
# plt.figure(figsize=(10, 6))
# plt.plot(df['时段'], df['PM2.5'], label='PM2.5')
# plt.xlabel('时间')
# plt.ylabel('PM2.5浓度 (µg/m³)')
# plt.title('PM2.5浓度随时间的变化')
# plt.legend()
# plt.show()

# 绘制污染物浓度分布图
plt.figure(figsize=(10, 6))
sns.histplot(df['PM2.5'], kde=True, bins=30)
plt.xlabel('PM2.5浓度 (µg/m³)')
plt.ylabel('频率')
plt.title('PM2.5浓度分布')
plt.show()

# 绘制风向与PM2.5浓度的关系
plt.figure(figsize=(10, 6))
sns.boxplot(x=df['风向'], y=df['PM2.5'])
plt.xlabel('风向 (度)')
plt.ylabel('PM2.5浓度 (µg/m³)')
plt.title('不同风向下的PM2.5浓度')
plt.show()


# 3.------------------------------数据预处理-----------------------------------
# 3.1 处理缺失值(无缺失值)（-----测试-----）
print("缺失值统计:")
print(df.isnull().sum())


# 3.2 处理异常值（例如将 -99.0(E) 替换为 NaN）
pd.set_option('future.no_silent_downcasting', True)
df.replace('-99.0(E)', np.nan, inplace=True)

# 3.3 将非数值类型的数据转换为数值类型
for col in df.columns[3:]:  # 从第4列开始处理
    df[col] = pd.to_numeric(df[col], errors='coerce')  # 将非数值类型转换为 NaN

# 3.4 检查全为 NaN 的列
nan_columns = df.columns[df.isnull().all()]  # 找到全为 NaN 的列
# print("全为 NaN 的列:", nan_columns)

# 3.5 删除全为 NaN 的列
df.drop(columns=nan_columns, inplace=True)
# print("删除全为 NaN 的列后的数据:")#(------测试-----)
# print(df.head())

# 4. ------------------------------数据归一化-----------------------------------
# 4.1 Min-Max 归一化
min_max_scaler = MinMaxScaler()
df_min_max = pd.DataFrame(min_max_scaler.fit_transform(df.iloc[:, 3:]), columns=df.columns[3:])
df_min_max['时段'] = df['时段']  # 保留时间列
# print("Min-Max 归一化后的数据:")#(------测试-----)
# print(df_min_max.head())

# 4.2 Z-Score 归一化
z_score_scaler = StandardScaler()
df_z_score = pd.DataFrame(z_score_scaler.fit_transform(df.iloc[:, 3:]), columns=df.columns[3:])
df_z_score['时段'] = df['时段']  # 保留时间列
# print("Z-Score 归一化后的数据:")#(------测试-----)
# print(df_z_score.head())

# 4.3 可视化归一化后的数据（以 PM2.5 为例）
plt.figure(figsize=(12, 6))
plt.plot(df['时段'], df['PM2.5'], label='原始数据', color='blue')
plt.plot(df_min_max['时段'], df_min_max['PM2.5'], label='Min-Max 归一化', color='red')
plt.plot(df_z_score['时段'], df_z_score['PM2.5'], label='Z-Score 归一化', color='green')
plt.xlabel('时间')
plt.ylabel('PM2.5浓度')
plt.title('PM2.5浓度归一化对比')
plt.legend()
plt.show()

# 5. ----------------------------相关性分析----------------------------------------
# 5.1 计算相关性矩阵
corr_matrix = df.iloc[:, 3:].corr()

# 5.2 可视化相关性矩阵（热力图）
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('属性相关性热力图')
plt.show()
